﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
using Xceed.Wpf.Toolkit;

namespace chat_winform_wpf
{
    class Common
    {
    }

    class UserLoginInfo
    {
        static public UserLoginInfo _rli = new UserLoginInfo();
        static public UserLoginInfo GetInstance()
        {
            return _rli;
        }


        public Int64 UserNo = 0; // 0 自己， 1 对方
    }

    public class NIMIMMessage
    {
        public Int64 SenderID;
        public NIMMessageType MessageType;
    }

    public enum NIMMessageType
    {
        kNIMMessageTypeAudio = 1,
        kNIMMessageTypeVideo = 2,
        kNIMMessageTypeFile = 3,
        kNIMMessageTypeImage = 4,
        kNIMMessageTypeText = 5
    }

    public class NIMTextMessage
    {
        public string TextContent;
    }

    public class Text: NIMIMMessage
    {
        public string TalkID { get; set; }
        public string TextContent { get; set; }
        public string MessageWidth { get; set; }
    }

    public class EmoticonText
    {
        public string Key { get; set; }

        public List<List<ChatMessage>> rtfText;
        //public string Value { get; set; }
    }

    class MessageDataTemplateSelector : DataTemplateSelector
    {

        public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
        {
            UserControl userControl = FindParent<UserControl>(container as FrameworkElement); ;

            //DataTemplate dataTemplate = at.FindResource("friend_text") as DataTemplate;
            //System.Windows.Window win = Application.Current.MainWindow;
            var myUserNo = UserLoginInfo.GetInstance().UserNo;
            if (item != null)
            {
                NIMIMMessage m = item as NIMIMMessage;
                if (m.SenderID == myUserNo)
                {
                    switch (m.MessageType)
                    {
                        case NIMMessageType.kNIMMessageTypeAudio:
                        case NIMMessageType.kNIMMessageTypeVideo:
                            return userControl.FindResource("self_media") as DataTemplate;
                        case NIMMessageType.kNIMMessageTypeFile:
                            return userControl.FindResource("self_file") as DataTemplate;
                        case NIMMessageType.kNIMMessageTypeImage:
                            return userControl.FindResource("self_image") as DataTemplate;
                        case NIMMessageType.kNIMMessageTypeText:
                            return userControl.FindResource("self_text") as DataTemplate;
                        default:
                            break;
                    }
                }
                else
                {
                    switch (m.MessageType)
                    {
                        case NIMMessageType.kNIMMessageTypeAudio:
                        case NIMMessageType.kNIMMessageTypeVideo:
                            return userControl.FindResource("friend_media") as DataTemplate;
                        case NIMMessageType.kNIMMessageTypeFile:
                            return userControl.FindResource("friend_file") as DataTemplate;
                        case NIMMessageType.kNIMMessageTypeImage:
                            return userControl.FindResource("friend_image") as DataTemplate;
                        case NIMMessageType.kNIMMessageTypeText:
                            return userControl.FindResource("friend_text") as DataTemplate;
                        default:
                            break;
                    }
                }
            }
            return null;
        }

        public static T FindParent<T>(FrameworkElement element) where T : FrameworkElement
        {
            FrameworkElement parent = VisualTreeHelper.GetParent(element) as FrameworkElement;

            while (parent != null)
            {
                T correctlyTyped = parent as T;

                if (correctlyTyped != null)
                    return correctlyTyped;
                else
                    return FindParent<T>(parent);
            }

            return null;
        }
    }



    public class ShowImageOrText : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            List<ChatMessageRow> v = JsonConvert.DeserializeObject<List<ChatMessageRow>>((string)value);
            StringBuilder sb = new StringBuilder();
            string rowtext = "";
            foreach (ChatMessageRow lc in v)
            {
                rowtext = "";

                if(lc.rowType == "Paragraph")
                {
                    rowtext += "<Paragraph>";
                    foreach (ChatMessage cm in lc.rowMessaget)
                    {
                        if (cm.messageType == 0)
                        {
                            rowtext += "<Run>" + cm.text + "</Run>";
                        }
                        else if (cm.messageType == 1)
                        {
                            rowtext += $"<Image Width=\"{cm.param1}\" Height=\"{cm.param2}\" Source=\"{cm.text}\"/>";
                        }
                    }
                    rowtext += "</Paragraph>";
                    sb.Append(rowtext);
                }
                else
                {
                    rowtext += "<BlockUIContainer>";
                    foreach (ChatMessage cm in lc.rowMessaget)
                    {
                        if (cm.messageType == 0)
                        {
                            rowtext += "<Run>" + cm.text + "</Run>";
                        }
                        else if (cm.messageType == 1)
                        {
                            rowtext += $"<Image Width=\"{cm.param1}\" Height=\"{cm.param2}\" Source=\"{cm.text}\" />";
                        }
                    }
                    rowtext += "</BlockUIContainer >";
                    sb.Append(rowtext);
                }              

            }
            return @"<Section xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" FontFamily=""Microsoft YaHei"" xml:space=""preserve"" TextAlignment=""Left"" LineHeight=""Auto"">" + sb.ToString() + "</Section>";
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    class RTBXamlFormatter : ITextFormatter
    {
        public string GetText(System.Windows.Documents.FlowDocument document)
        {
            TextRange tr = new TextRange(document.ContentStart, document.ContentEnd);
            using (MemoryStream ms = new MemoryStream())
            {
                tr.Save(ms, DataFormats.Xaml);
                return ASCIIEncoding.Default.GetString(ms.ToArray());
            }
        }

        public void SetText(System.Windows.Documents.FlowDocument document, string text)
        {
            try
            {
                if (String.IsNullOrEmpty(text))
                {
                    document.Blocks.Clear();
                }
                else
                {
                    TextRange tr = new TextRange(document.ContentStart, document.ContentEnd);
                    using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(text)))
                    {
                        tr.Load(ms, DataFormats.Xaml);
                    }
                }
            }
            catch
            {
                throw new InvalidDataException("Data provided is not in the correct Xaml format.");
            }
        }
    }

    public class ChatMessage
    {
        public int messageType { get; set; }  // 0文字 1 图片 2,表情 3 连接， 5 gif，6 按钮（声音-按钮）7 视频
        public string text { get; set; }  // 文字内容或者 表情 或者 图片地址

        public string param1 { get; set; }
        public string param2 { get; set; }
        public string param3 { get; set; }
        public string param4 { get; set; }

    }

    public class ChatMessageRow
    {
        public string rowType { get; set; }  // flowdocument里面包含的类型 是Paragraph 还是BlockUIContainer
        public List<ChatMessage> rowMessaget { get; set; }
    }
}
